import socket
import binascii
import select
import time
import asyncio
from select import *
from util.DLT698 import GetRequestNormal, SetRequestNormal, ActionRequest,GetCompletionFra,GetResponseNormal,ServiceJudgment
from util.Encoder import *
from util.MeterDoc import *
from util.tool import *
from util.protocol_dx import Protocol_Dx
from test_ProtocolConsistency.test_GET import*
from test_ProtocolConsistency.test_AppLayer import*
from test_002_ReadTerminalInfo import ReadTerminalInfo
class server():
    
    def start_server(self):
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = '192.168.1.99'  
        port = 8000
        ip_port = (host,port)
        server_socket.bind(ip_port)
        server_socket.listen(5)
        client_socket, addr = server_socket.accept()
        self.set_client_socket(client_socket)
        print("连接地址:{}".format(addr))
    def Io_multiplexing(self):
        poller=poll()
        poller.register(self.server_socket, select.POLLIN)
        # 存储连接的字典
        connections = {}
        addresses = {}

        while 1:
            events = poller.poll()
            for fd,event in events:
                if fd == self.server_socket.fileno():
                    # 接受新的连接
                    conn, addr = self.server_socket.accept()
                    print(f"Connected by {addr}")
                    conn.setblocking(False)
                    connections[conn.fileno()] = conn
                    addresses[conn.fileno()] = addr
                    poller.register(conn, select.POLLIN)
                elif event & select.POLLIN:
                    data = connections[fd].recv(1024)
                    if data:
                        print(f"Received data: {data.decode()}")
                        # Echo back the data
                        connections[fd].sendall(data)
                    else:
                        # 关闭连接
                        print(f"Closing connection from {addresses[fd]}")
                        poller.unregister(fd)
                        connections[fd].close()
                        del connections[fd]
                        del addresses[fd]

    def set_server_socket(self,server_socket):
        self.server_socket=server_socket
    def set_client_socket(self,client_socket):
        self.client_socket=client_socket
    def get_client_socket(self):
        return self.client_socket
    def recv(self):
        data = self.client_socket.recv(2048)
        hex_data = binascii.hexlify(data).decode('ascii')
        print("接收的报文:{}".format(hex_data))
        return self.dedcode(hex_data)["apdu"]
    def server_program(self):
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = '192.168.1.99'  
        port = 8000
        ip_port = (host,port)
        server_socket.bind(ip_port)
        server_socket.listen(5)
        client_socket, addr = server_socket.accept()
        self.set_client_socket(client_socket)
        print("连接地址:{}".format(addr))
        # self.start_server()
        data =self.client_socket.recv(1024)
        hex_data = binascii.hexlify(data).decode('ascii')
        print("接收的报文:{}".format(hex_data))
        apdu=self.dedcode(hex_data)["apdu"]
        self.lginh(apdu)
        # se = AppLayer(client_socket=self.client_socket)
        # se.SR()
        # se.ASF()
        # re=ReadTerminalInfo(client_socket=self.client_socket)
        # re.ReadTerminalInfo()
        # from test_003_ClockCallsAndSynchronizes import ClockCallsAndSynchronizes
        # cl = ClockCallsAndSynchronizes(client_socket=self.client_socket)
        # cl.ClockCallsAndSynchronizes()
        # from test_019_TerminalActiveReporting import TerminalActiveReporting
        # te = TerminalActiveReporting(client_socket=self.client_socket)
        # te.TerminalActiveReporting()
        from test_020_TerminalTimeMatcheEvent import TerminalTimeMatcheEvent
        te=TerminalTimeMatcheEvent(client_socket=self.client_socket)
        te.TerminalTimeMatcheEvent()
        # while True:
        #     apdu = self.recv()
            # if apdu[:2]=="01":
            #     fra_send=self.LINK_Response(apdu)
            #     self.Send_fr(fra_send)#报文 message
        #         SET.set()
        #         # client_socket.close()
    def lginh(self,apdu):
        if apdu[:2]=="01":
            fra_send=self.LINK_Response(apdu)
            self.Send_fr(fra_send)#报文 message
    async def Login_heartbeat_processing(self):
        while True:
            data = self.client_socket.recv(1024)
            hex_data = binascii.hexlify(data).decode('ascii')
            print("接收的报文:{}".format(hex_data))
            apdu = self.dedcode(hex_data)["apdu"]
            if apdu[:2]=="01":
                fra_send=self.LINK_Response(apdu)
                # message = "".encode()
                self.Send_fr(fra_send)#报文 message
    def Send_fr(self, frame_send: str, mes_op: str = "", is_return=0,reader=0):
        if mes_op:
            print(mes_op)
        prt = Protocol_Dx()
        sendf = prt.set_address(getTerAddr("000000000003")).set_address_type("0").set_link_user_data(frame_send).format_frame_string(ctrl=0x01)
        print("发送报文: " + tool.add_spaces_every_two_chars(sendf))
        # frame_send = prt.parser_frame(sendf).get_link_user_data().replace(" ","").lower()
        data = binascii.unhexlify(sendf)
        self.client_socket.send(data)
        return data
        if writer:
            writer.write(data)
        else:
            self.client_socket.send(data)
        # data = self.client_socket.recv(1024)
        # hex_data = binascii.hexlify(data).decode('ascii')
        
        # apdu = self.dedcode(hex_data)["apdu"]
        # if apdu[:2]=="01":
        #     fra_send=self.LINK_Response(apdu)
        #     # message = "".encode()
        #     self.Send_fr(fra_send)#报文 message
        # else:
        #     # print("接收的报文:{}".format(hex_data))
        #     if not is_return:
        #         dar = ServiceJudgment(apdu)
        #         if dar[1] == "00":
        #             self.append_step(mes_op + " 成功")
        #             return True
        #         else:
        #             self.append_step(mes_op + " 失败")
        #             self.Is_qualified = 0
        #             return False
        #     else:
        #         self.append_step("回复apdu：" + apdu)
        #         return apdu    
    def LINK_Response(self,apdu):
        dic=self.LINK_Request(apdu)
        apdu="81"+dic["piid"]+"80"+dic["time"]
        resp_time=self.MakeDateTime()
        apdu+=resp_time+resp_time
        return apdu
    def dedcode(self,fram):
        dic={}
        dic["rise"]=fram[2:6]
        dic["contr"]=fram[6:8]
        dic["server_addr"]=fram[8:24]
        dic["verify"]=fram[24:28]
        dic["apdu"]=fram[28:-6]
        return dic
    def LINK_Request(self,apdu):
         dic = {}
         dic["server"]=apdu[:2]
         dic["piid"]=apdu[2:4]
         dic["type"]=apdu[4:6]
         dic["Heartbeat"]=apdu[6:10]
         dic["time"]=apdu[10:]
         return dic
    def MakeDateTime(self):
        tm = datetime.datetime.now()
        t = extract_digits(str(tm))
        week = "0"+str(datetime.date.today().weekday()+1)
        lt = t[:8]
        rt = t[8:17]
        return En_DateTime(lt+week+rt)
class myclass(server):
    def __init__(self, y_esam_no=1, energy_unit=1, address=1, exec_notify=1, full_fra=1):
        super().__init__(y_esam_no, energy_unit, address, exec_notify, full_fra)
        self.tasks=[]
    async def Login_heartbeat_processing(self,reader, writer):
        while True:
            data = await reader.read(1024)
            hex_data = binascii.hexlify(data).decode('ascii')
            print("接收的报文:{}".format(hex_data))
            apdu = self.dedcode(hex_data)["apdu"]
            if apdu[:2]=="01":
                fra_send=self.LINK_Response(apdu)
                # message = "".encode()
                fra = self.Send_fr(fra_send,writer)
                print("fra:",fra)
                writer.write(fra)
            await writer.drain()
            # await asyncio.sleep(60)  # 等待60秒再次接收心跳
    async def set(self,reader, writer):
        await asyncio.sleep(100)
        me = "set 1-4 设置一个对象属性请求 测试开始"
        self.append_step(me)
        mes = "SET_{}:".format(1)
        mes_op = "请求设置[日期时间]"
        oad = "40000200"
        data = "1C" + self.get_time(0, full_time=1,is_16=1)
        frame_send = SetRequestNormal(oad,data)
        apdu = self.Send_fr(frame_send, mes, is_return=1,reader=reader, writer=writer)
        try:
            _,dar = ServiceJudgment(apdu)
        except:
            self.append_step(mes + "应答错误 测试失败")
            self.Is_qualified = 0
            self.YorN(mes)
            return
        if dar == "00":
            self.append_step(mes + " 成功")
        else:
            self.append_step(mes + " 失败")
            self.Is_qualified = 0
    async def handle_connection(self, reader, writer):
        self.tasks.append(asyncio.create_task(self.Login_heartbeat_processing(reader, writer)))
        self.tasks.append(asyncio.create_task(self.set(reader, writer)))
    async def main(self,host="192.168.1.99",port=8000):
        server = await asyncio.start_server(self.handle_connection, host, port)
        async with server:
            await server.serve_forever()
    def Send_fr(self, frame_send: str, mes_op: str = "", is_return=0,reader=0, writer=0):
        if mes_op:
            self.append_step(mes_op)
        prt = Protocol_Dx()
        sendf = prt.set_address(getTerAddr("000000000003")).set_address_type("0").set_link_user_data(frame_send).format_frame_string(ctrl=0x01)
        self.append_step("发送报文: " + tool.add_spaces_every_two_chars(sendf))
        # frame_send = prt.parser_frame(sendf).get_link_user_data().replace(" ","").lower()
        data = binascii.unhexlify(sendf)
        return data        
if __name__ == '__main__':
    ser=server()
    ser.server_program()
    
    # t=myclass()
    # try:
    #     asyncio.run(t.main())
    # except KeyboardInterrupt:
    #     pass